import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User } from 'src/schemas/user/user.interface';
import { UpdateUserDto } from 'src/dto/update-user.dto';
import { UsersPaginationDto } from 'src/dto/users-pagination.dto';

@Injectable()
export class UsersService {
  constructor(@InjectModel('User') private readonly userModel: Model<User>) {}

  /**
   * 创建一个用户
   * @param openid 用户唯一标识
   * @param nickName 昵称
   */
  create(openid: string, nickName: string) {
    const createdUser = new this.userModel({
      openid,
      nickName,
    } as User);

    return createdUser.save();
  }

  /**
   * 通过 _id 查找用户
   * @param _id _id
   */
  findById(_id: string) {
    return this.userModel.findOne({ _id });
  }

  /**
   * 通过 _id 删除一个用户
   * @param _id 用户唯一标识
   */
  deleteById(_id: string) {
    return this.userModel.deleteOne({ _id });
  }

  /**
   * 通过 _id 更新一个用户
   * @param _id _id
   * @param updateUserDto 更新的用户信息
   */
  updateById(_id: string, updateUserDto: UpdateUserDto) {
    return this.userModel.updateOne({ _id }, updateUserDto);
  }

  /**
   * 查询一些用户
   * @param usersPaginationDto 查询条件
   */
  find(usersPaginationDto: UsersPaginationDto) {
    const { pageIndex, pageSize, keyword } = usersPaginationDto;
    const reg = new RegExp(keyword, 'i');
    const conditions = {
      $or: [{ phoneNumber: { $regex: reg } }, { nickName: { $regex: reg } }],
    };

    return this.userModel
      .find(conditions, '-__v')
      .skip((pageIndex - 1) * pageSize)
      .limit(pageSize);
  }

  /**
   * 获得用户的总数
   */
  count(usersPaginationDto: UsersPaginationDto) {
    const { keyword } = usersPaginationDto;
    const reg = new RegExp(keyword, 'i');
    const conditions = {
      $or: [{ phoneNumber: { $regex: reg } }, { nickName: { $regex: reg } }],
    };

    return this.userModel.find(conditions).countDocuments();
  }

  /**
   * 若找到用户则返回用户，若没有找到则创建后返回
   * @param openid 用户唯一标识
   */
  async findAndCreateByOpenid(openid: string, nickName: string) {
    const user = await this.userModel.findOne({ openid });
    if (user) {
      return user;
    } else {
      return this.create(openid, nickName);
    }
  }
}
